package wc

import (
	"fmt"
	"github.com/astaxie/beego/context"
	"github.com/boltdb/bolt"
	"github.com/silenceper/wechat"
	"github.com/silenceper/wechat/cache"
	"github.com/silenceper/wechat/menu"
	"github.com/silenceper/wechat/message"
	"github.com/silenceper/wechat/user"
	"log"
	"main/env"
	"main/session"
	"net/url"
	"strings"
)

var Wc *wechat.Wechat

func init() {
	var rediscache = cache.NewRedis(&cache.RedisOpts{
		Host:        env.RedisHost,
		Database:    env.RedisDB,
		MaxIdle:     20,
		MaxActive:   300,
		IdleTimeout: 24,
	})

	config := &wechat.Config{
		AppID:          env.AppID,
		AppSecret:      env.AppSecret,
		Token:          env.Token,
		EncodingAESKey: "2LAr21PpDL0DPuHVUXrTyyfjJ7pwntQeJCChcj838vv",
		Cache:          rediscache,
	}

	Wc = wechat.NewWechat(config)

	m := Wc.GetMenu()
	err := SetButton(m)
	if err != nil {
		log.Fatalln("button set error", err)
	}
}

func Index(ctx *context.Context) {

	server := Wc.GetServer(ctx.Request, ctx.ResponseWriter)

	server.SetMessageHandler(func(msg message.MixMessage) *message.Reply {

		U := GetUser(server)

		switch msg.MsgType {

		case message.MsgTypeText:
			{

				if msg.Content == "0" {
					U.SetMode(NoneMode)
					return NewTextMessage(OnNoneMode)
				}
				if msg.Content == "1" {
					U.SetMode(BookMode)
					return NewTextMessage(OnBookMode)
				}
				if msg.Content == "2" {
					U.SetMode(LoveMode)
					return NewTextMessage(rHelpLove)
				}
				if msg.Content == "3" {
					U.SetMode(BindGrade)
					return NewTextMessage(BindGradeStep1)
				}
				if msg.Content == "4" {
					fmt.Println(U.InfoDetail)
					fmt.Println(U.InfoDetail.UnionID)
					return NewTextMessage(U.InfoDetail.UnionID)
				}
				if msg.Content == "解绑" {
					return NewTextMessage(Unbind(U.InfoDetail.UnionID))
				}

				switch U.Mode {
				case NoneMode:
					{
						// 无论用户回复什么都会进入NoneMode，
						return NewTextMessage(OnNoneMode)
					}
				case BookMode:
					{
						res := RunBookServer(msg.Content)
						return NewTextMessage(res + TAIL)
					}
				case LoveMode:
					{

						// 开始获取当前love的状态
						loveMode, err := U.GetCTX(CTXLoveMode)
						if err != nil {
							log.Println(err)
						} else {
							// 有状态回复
							if loveMode.(string) == "prelove" {

								if msg.Content == "取消" {
									defer U.SetCTX(CTXLoveMode, "")
									return NewTextMessage("「已取消」心愿大声说出来才会实现哟！" + LoveTail + TAIL)
								}

								if msg.Content == "确定" {
									c, err := U.GetCTX(CTXLoveBuffer)
									if err != nil {
										return NewTextMessage("表白内容为空！" + "\n请直接回复积极正向的表白(520字内), 寻人或求偶信息 或<a href='weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=取消'>点我取消表白</a> 或回复「取消」以取消")
									}

									params := url.Values{}
									params.Add("func", "create")
									params.Add("content", c.(string))
									params.Add("oid", U.OpenID)
									res := RunLoveModule(params.Encode())
									U.CTX[CTXLoveBuffer] = ""
									U.SetCTX(CTXLoveMode, "")
									return NewTextMessage(res)
								}

								_ = U.SetCTX(CTXLoveBuffer, msg.Content)

								return NewTextMessage("确定表白的内容为：\n\n" + msg.Content + "\n\n吗？\n" +
									UrlButton("取消", "❌取消表白") + "\t " +
									UrlButton("确定", "✅确定发送"))

							}

						}
						if msg.Content == "帮助" {
							return NewTextMessage(rHelpLove)
						}
						if msg.Content == "发送" {
							err := U.SetCTX(CTXLoveMode, PreLove)
							if err != nil {
								return NewTextMessage(err.Error())
							}
							// 预备发送
							// preSendLove = "[预备备，发送！]\n请直接回复积极正向的心愿(520字内), 寻人或求偶信息，此条件下不可触发其他任何服务哟 或<a href='weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=取消'>点我取消发送</a> 或回复「取消」以取消"
							return NewTextMessage(preSendLove)
						}

						if strings.Contains(msg.Content, "搜索") {
							temp := strings.Split(msg.Content, " ")
							if len(temp) != 2 {
								return NewTextMessage("搜索请回复：「搜索 内容」,中间只包含一个空格")
							}
							params := url.Values{}
							params.Add("func", "search")
							params.Add("keyword", temp[1])
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}

						if strings.Contains(msg.Content, "随机") {
							temp := strings.Split(msg.Content, " ")
							if len(temp) != 2 {
								return NewTextMessage("随机查看请回复：「随机 num」,中间只包含一个空格")
							}
							params := url.Values{}
							params.Add("func", "random")
							params.Add("num", temp[1])
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}

						if msg.Content == "最新" {
							params := url.Values{}
							params.Add("func", "view")
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}

						if strings.Contains(msg.Content, "like") {
							temp := strings.Split(msg.Content, " ")
							if len(temp) != 2 {
								return NewTextMessage("「如何点赞」\n回复「like num」中间有一个空格，num代表要点赞的表白编号。\n例如「like 1」")
							}
							params := url.Values{}
							params.Add("func", "like")
							params.Add("id", temp[1])
							params.Add("oid", U.OpenID)
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}

						if strings.Contains(msg.Content, "get") {
							temp := strings.Split(msg.Content, " ")
							if len(temp) != 2 {
								return NewTextMessage("「如何获取指定的表白」\n回复「get hash」中间有一个空格，hash是目标区块的hash")
							}
							params := url.Values{}
							params.Add("func", "get")
							params.Add("hash", temp[1])
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}

						if strings.Contains(msg.Content, "reply") {
							temp := strings.Split(msg.Content, " ")
							if len(temp) != 2 {
								return NewTextMessage("「如何回复表白」\n回复「reply num」中间有一个空格，num是目标编号")
							}
							params := url.Values{}
							params.Add("func", "reply")
							params.Add("hash", temp[1])
							res := RunLoveModule(params.Encode())
							return NewTextMessage(res)
						}
						return NewTextMessage(rHelpLove)

					}
				case BindGrade:
					{
						// 去除两边的空格
						var content = strings.TrimSpace(msg.Content)

						// 如果是个学号
						if len(content) == 8 {
							// 设置临时的值
							_ = U.SetCTX("uid", content)
							return NewTextMessage(fmt.Sprintf("『确认！！！』\n提醒学号为%s的同学，这里是成绩通知，请勿恶意绑定，\n回复身份证前两位可以确认「防止恶意绑定」\n或直接回复新的学号更正", content))
						}

						// 如果是身份证前两位
						if len(msg.Content) == 2 {

							// 获取学号，从缓存中获取学号
							r, _ := U.GetCTX("uid")
							// 获取身份证
							sid, err := RunIDServer(r.(string))
							if err != nil {
								return NewTextMessage(err.Error())
							}
							// 身份证为空
							if sid == "" {
								_ = QuickDown("int_server", "身份证为空", r.(string))
								return NewTextMessage("当前账户绑定出现问题，已经通知")
							}
							if sid[0:2] == content {
								err := user.NewUser(server.Context).UpdateRemark(U.OpenID, r.(string))
								if err != nil {
									return NewTextMessage(err.Error())
								}
								err = session.GetDb().Update(func(tx *bolt.Tx) error {

									b := tx.Bucket(session.DBStudents)
									if b != nil {
										err := b.Put([]byte(r.(string)), []byte(U.OpenID))
										if err != nil {
											return err
										}
									}
									return nil
								})
								if err != nil {
									return NewTextMessage(err.Error())
								}

								return NewTextMessage(U.OpenID + " 绑定成功")
							}
						}
					}
				}

			}

		case message.MsgTypeEvent:
			switch msg.Event {
			case message.EventSubscribe:
				articles := make([]*message.Article, 1)
				article := new(message.Article)
				article.Title = "杂货铺使用方式"
				article.Description = "懒得看在下方回复「帮助」试试(不要「」)"
				article.URL = "https://mp.weixin.qq.com/s/9EJLkVcFGk4zqqnxnmv5EA"
				article.PicURL = "https://imgkr.cn-bj.ufileos.com/012cc235-fc34-4328-8e44-0d658b062eed.png"
				articles[0] = article
				news := message.NewNews(articles)
				return &message.Reply{MsgType: message.MsgTypeNews, MsgData: news}
			case message.EventClick:
				{
					switch msg.EventKey {
					case "guide":
						{
							articles := make([]*message.Article, 1)
							article := new(message.Article)
							article.Title = "杂货铺使用方式"
							article.Description = "2020-02-22更新"
							article.URL = "https://mp.weixin.qq.com/s/9EJLkVcFGk4zqqnxnmv5EA"
							article.PicURL = "https://imgkr.cn-bj.ufileos.com/012cc235-fc34-4328-8e44-0d658b062eed.png"
							articles[0] = article
							news := message.NewNews(articles)
							return &message.Reply{MsgType: message.MsgTypeNews, MsgData: news}
						}
					case "bind_unbind":
						{

							return NewTextMessage(DoAuth(U.InfoDetail.UnionID))
						}
					case "privacy":
						{
							return NewTextMessage("我们在开发过程中尽可能的避免了留存和用户相关的信息，在一定程度上只作为信息的传递者。但是" +
								"有时候难免因为用户体验相关的原因，储存了一定的缓存，若这点让用户感到不适，我们深表道歉，并愿意提供帮助在我们的服务器中抹去任何与您有关的信息，请悉知。\n\n" +
								"我们按照行业规则来储存用户信息（Cookie），通过该用户信息不可能反查到用户本身。")
						}
					case "feedback":
						{
							return NewTextMessage("请直接通过<a href ='https://www.wjx.cn/jq/60412701.aspx'>点我填写问题</a>\n\n或通过github题ISSUE\n\nhttps://github.com/dashjay/integer_deploy")
						}
					case "grade":
						{
							return NewTextMessage("新成绩通知正在开发中，预计期中前开放绑定")
						}

					case "intro":
						{
							articles := make([]*message.Article, 1)
							article := new(message.Article)
							article.Title = "杂货铺介绍"
							article.Description = "这只是一份情怀"
							article.URL = "https://mp.weixin.qq.com/s/39MJXEuAaVDBD799UWoE0A"
							article.PicURL = "https://mmbiz.qpic.cn/mmbiz_jpg/Rs5L1kEr0nYkmVutcMBd9GDlsHsrDwPSNkjrSLvQQiaS8Z95dibUqZicD4HGnjovxA2VIPOYNYnTsGEhZZbKZWkzg/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1"
							articles[0] = article
							news := message.NewNews(articles)
							return &message.Reply{MsgType: message.MsgTypeNews, MsgData: news}
						}
					case "contact":
						{
							return NewTextMessage("请加微信zhaofang0903，并注明杂货铺，和联系原因")
						}

					case "1":
						U.SetMode(BookMode)
						return NewTextMessage(OnBookMode)
					case "2":
						U.SetMode(LoveMode)
						return NewTextMessage(rHelpLove)

					default:
						return NewTextMessage("系统似乎出了点问题，没有理解这一条指令是什么。")

					}
				}
			}
		}

		//回复消息：演示回复用户发送的消息
		return NewTextMessage(msg.Content)
	})

	//处理消息接收以及回复
	err := server.Serve()

	if err != nil {
		fmt.Println(err)
		return
	}

	server.Send()
}

func NewTextMessage(text string) *message.Reply {
	return &message.Reply{MsgType: message.MsgTypeText, MsgData: message.NewText(text)}
}

func UrlButton(msg, title string) string {
	return fmt.Sprintf("<a href='weixin://bizmsgmenu?msgmenuid=1&msgmenucontent=%s'>%s</a>", msg, title)
}

// SetButton 设置buttons
func SetButton(m *menu.Menu) error {

	// 定义第一个菜单
	kv := map[string]string{
		"使用指南":  "guide",
		"绑定&解绑": "bind_unbind",
		"隐私协议":  "privacy",
		"意见反馈":  "feedback",
	}
	buttons0 := make([]*menu.Button, len(kv))
	i := 0
	for k, v := range kv {
		btn := new(menu.Button)
		btn.SetClickButton(k, v)
		buttons0[i] = btn
		i++
	}
	btn0 := new(menu.Button)
	btn0.SetSubButton("绑定&使用", buttons0)

	// 第二个菜单
	kv = map[string]string{
		"贝壳刷题宝": "wx135149a0f60850e2",
		"课表":    "wx38a32006d9373a1f",
	}

	buttons1 := make([]*menu.Button, len(kv))

	i = 0
	for k, v := range kv {
		btn := new(menu.Button)
		btn.SetMiniprogramButton(k, "http://test.com", v, "/pages/table/table")
		buttons1[i] = btn
		i++
	}
	kv = map[string]string{
		"找书":  "1",
		"表白墙": "2",
	}

	buttons11 := make([]*menu.Button, len(kv))

	i = 0
	for k, v := range kv {
		btn := new(menu.Button)
		btn.SetClickButton(k, v)
		buttons11[i] = btn
		i++
	}
	buttons1 = append(buttons1, buttons11...)

	btn1 := new(menu.Button)
	btn1.SetSubButton("贝壳の程序", buttons1)

	// 第三个菜单
	kv = map[string]string{
		"杂货铺简介": "intro",
		"联系我们":  "contact",
	}
	buttons2 := make([]*menu.Button, len(kv))

	i = 0
	for k, v := range kv {
		btn := new(menu.Button)
		btn.SetClickButton(k, v)
		buttons2[i] = btn
		i++
	}
	btn2 := new(menu.Button)
	btn2.SetSubButton("活动&简介", buttons2)

	mainButton := make([]*menu.Button, 3)
	mainButton[0] = btn0
	mainButton[1] = btn1
	mainButton[2] = btn2

	err := m.SetMenu(mainButton)
	if err != nil {
		fmt.Printf("err= %v", err)
	}

	return nil
}
